package com.jsftoolkit.gen.writer;

import javax.faces.webapp.UIComponentELTag;

/**
 * Interface for {@link ClassWriter}s that generate the code for a tag class.
 * <p>
 * Implementations should prefer the use of {@link ClassWriter} methods to
 * printing code directly whenever possible.
 * 
 * @author noah
 * 
 */
public interface TagWriter extends ClassWriter {

	/**
	 * Prints the component import statements. This also informs the writer of
	 * what the component package and class name are.
	 * 
	 * @param componentPackage
	 * @param componentClass
	 */
	void printComponentImport(String componentPackage, String componentClass);

	/**
	 * Creates a member field for the given name (ValueExpression or Binding)
	 * 
	 * @param name
	 */
	void printAttributeField(String name);

	/**
	 * Prints a component attribute set statement. The JSF 1.2 spec and good
	 * programming practice recommend that each component attribute have a
	 * corresponding string constant declared on the component class whose value
	 * is the name of that attribute. If such a constant exists, its name e.g.
	 * "SOME_CONSTANT" should be specified as <code>constantName</code>.
	 * <p>
	 * There may also be attributes that are only important to the renderer, so
	 * they do not have a constant on the class. If such an attribute is being
	 * specified, <code>constantName</code> should be null.
	 * 
	 * @param name
	 *            the name of the field backing this attribute (also doubles at
	 *            the attribute name if key is null).
	 * @param constantName
	 *            the string constant on the component class whose value is the
	 *            attribute name.
	 */
	void printPropertySet(String name, String constantName);

	/**
	 * Starts the {@link UIComponentELTag#setProperties} method.
	 */
	void startSetProperties();

	/**
	 * Prints accessors for the attributes specified (via
	 * {@link #printAttributeField(String)}) thus far.
	 */
	void printAccessors();

	/**
	 * Prints getters to retrieve the COMPONENT_TYPE and DEFAULT_RENDERER_TYPE
	 * values. i.e. {@link UIComponentELTag#getComponentType()} and
	 * {@link UIComponentELTag#getRendererType()}.
	 * <p>
	 * Implementations can expect that the component class (if imported) has
	 * COMPONENT_TYPE and DEFAULT_RENDERER_TYPE constants as per the JSF 1.2
	 * spec.
	 * 
	 * @param type
	 *            the component type. If the component class has been specified
	 *            (via {@link #printComponentImport(String, String)}), then
	 *            this should be null.
	 * @param rendererType
	 *            the default renderer type. Only necessary if the component
	 *            class was not specified.
	 */
	void printTypeAndRendererGetters(String type, String rendererType);

}
